#if !defined(___STD_H)
#define ___STD_H


#include <math.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/timeb.h>


#if defined(___SYS_I486)
#if !defined(___SYS_I386)
#define ___SYS_I386
#endif
#endif
#if defined(___DLLIMP)
#if defined(___OS_WIN) && defined(__GNUC__)
#define dllimp           __declspec(dllimport)
#elif defined(___OS_LIN)
#define dllimp
#else
#error Missing option
#endif
#else
#define dllimp
#endif


typedef void xx;
typedef float R4;
typedef unsigned char  N1;
typedef unsigned short int N2;
typedef unsigned long  int N4;
typedef   signed char  I1;
typedef   signed short int I2;
typedef   signed long  int I4;
typedef xx *Ptr;
typedef N1 *Str;
#if !defined(___ROPT)
typedef R4 RI;
#define  _ri "%f"
#define RoundRI(x) RoundR4(x)
#define dumpRI(s,t) dumpR4(s,t)
#else
typedef I4 RI;
#define _ri "%li"
#define RoundRI(x) (x)
#define dumpRI(s,t) dumpI4(s,t)
#endif


#if !defined(NULL)
#define NULL                      ((Ptr)0ul)
#endif
#define NO                        0
#define YES                       1
#define BEG                       do {
#define END                       } while (0)
#define DEB0(s)                   msg(4,s)
#define DEB1(s,n1)                msg(4,s,n1)
#define DEB2(s,n1,n2)             msg(4,s,n1,n2)
#define DEB3(s,n1,n2,n3)          msg(4,s,n1,n2,n3)
#define INF0(s)                   msg(3,s)
#define INF1(s,n1)                msg(3,s,n1)
#define INF2(s,n1,n2)             msg(3,s,n1,n2)
#define INF3(s,n1,n2,n3)          msg(3,s,n1,n2,n3)
#define INF4(s,n1,n2,n3,n4)       msg(3,s,n1,n2,n3,n4)
#define INF5(s,n1,n2,n3,n4,n5)    msg(3,s,n1,n2,n3,n4,n5)
#define MSG1(s,n1)                msg(3,"[%08lX] " s "\n",n1)
#define MSG2(s,n1,n2)             msg(3,"[%08lX] " s "\n",n1,n2)
#define MSG3(s,n1,n2,n3)          msg(3,"[%08lX] " s "\n",n1,n2,n3)
#define MSG4(s,n1,n2,n3,n4)       msg(3,"[%08lX] " s "\n",n1,n2,n3,n4)
#define WARN1(s,n1)               msg(2,"[%08lX] \n  " s "\n",n1)
#define WARN2(s,n1,n2)            msg(2,"[%08lX] \n  " s "\n",n1,n2)
#define ERR1(s,n1)                BEG msg(1,"[%08lX] " s "  {%lu}\n",n1,n1); \
                                  return (-1); END
#define ERR2(s,n1,n2)             BEG msg(1,"[%08lX] " s "  {%lu}\n",n1,n2,n1); \
                                  return (-1); END
#define ERR3(s,n1,n2,n3)          BEG msg(1,"[%08lX] " s "  {%lu}\n",n1,n2,n3,n1); \
                                  return (-1); END
#define ERR4(s,n1,n2,n3,n4)       BEG msg(1,"[%08lX] " s "  {%lu}\n",n1,n2,n3,n4,n1); \
                                  return (-1); END
#define GETC                      BEG ii=fgetc(fi); cc=(N1)ii; \
                                  if (ii!=-1) ++nn; END
#define READ(s1,l1,n1,f1)         BEG ii=fread(s1,l1,n1,f1); \
                                  if (ii==n1) nn+=ii*l1; END
#define READ1(s1,l1,f1)           READ(s1,l1,1,f1)
#define ddcp(dd1,dd2)             MemCpy(dd1,dd2,64)
#define ddyx(dd,xd,y,x)           ((dd)+(((y)*(xd)+(x))<<6))

#define CNUM                      3          // CompNum
#define QMAX                      4          // QuantMax
#define HNUM                      2
#define HMAX                      (2*HNUM)   // HufMax


typedef struct _tApp
{ // 1.1
  N1 ver[2];
  // 0:pix,1:dpi,2:dpc
  N1 units;
  N2 xden,yden;
  N1 xthumb,ythumb;
} tApp;
typedef struct _tSof
{ // 8 bits
  N1 prec;
  N2 xl,yl;
  N1 comps;
} tSof;
typedef struct _tComp
{ N1 cid;
  // 1-4
  N1 xd,yd;
  // 0-3
  N1 qid;
} tComp;
typedef struct _tSos
{ N1 comps;
  N1 q1,q2;
  N1 ah,al;
  N2 dri;
} tSos;
typedef struct _tComp2
{ N1 cid;
  // 0-1
  N1 hdc;
  N1 hac;
} tComp2;
typedef struct _tQtab
{ // 0:8 bits
  N1 prec;
  N1 qid;
  N2 tab[64];
} tQtab;
typedef struct _tHtab
{ // 0:DC,1:AC
  N1 typ;
  N1 hid;
  N1 len[16];
  N1 *val;
  N1 ref[256];

  N2 hufnum;
  N1 *hufsiz;
  N2 *hufcod;
  N2 hufmin[16];
  N2 hufmax[16];
  N2 hufidx[16];
} tHtab;

typedef struct _tProg
{ N1 msg;
  FILE *fi,*fo,*fb;
} tProg;
typedef struct _tJpeg1
{ N1 xd[CNUM],yd[CNUM];
  N2 *tab1,*tab2;

  N1 xd0,yd0;
  N2 xl,yl,xm,ym;
  N4 *buf[CNUM];
  N4 len[CNUM];
  tHtab htab[HMAX];

  struct _tBmp *bmp;
  N1 *pp[CNUM];
  N4 *buf1[CNUM];
  N4 *buf2[CNUM];
} tJpeg1;
typedef struct _tJpeg2
{ tHtab htab[HMAX];
  struct _tBmp *bmp;
  N1 *pp[CNUM];
} tJpeg2;
typedef struct _tHuf
{ N4 *b1,*b2,i1;
  I2 n1,v1,d1;
  N1 len[32],*val;
  N2 hufnum;
} tHuf;
typedef struct _tItem
{ N4 num; N1 len;
  struct _tItem *next;
} tItem;
typedef struct _tGetBit
{ N4 *nn;
  FILE *f1;
  N1 cnt,bb;
} tGetBit,tPutBit;
typedef struct _tBmp
{ FILE *f1;
  N4 xm,ym,xm2;
  N4 xl,yl,xl2;
  N1 *pp;
} tBmp;


#if !defined(___STD_C)
extern dllimp tProg *prg;
#endif
#if !defined(___DCT_C)
extern dllimp N1 *zz1,*zz2;
extern dllimp RI *tt;
#endif


xx msg(N1 msg,Str fmt,...);
xx dumpN1(Str s1,N1 *dd);
xx dumpI2(Str s1,I2 *dd);
xx dumpI4(Str s1,I4 *dd);
xx dumpN4(Str s1,N4 *dd);
xx dumpR4(Str s1,R4 *dd);
Ptr MemGet(N4 len);
xx MemRel(Ptr p);
I4 MemCpy(Str s1,Str s2,N4 l);
Str StrCmp(Str s1,Str s2);
I4 StrLen(Str s1);
R4 RoundR4(R4 r1);

I4 opts1(tProg *prg,int argc,char **argv);
xx jpeg1Beg(tJpeg1 *jpg);
xx jpeg1End(tJpeg1 *jpg);
int jpeg1a(int argc,char **argv);
I4 jpeg1b(tJpeg1 *jpg,FILE *fi,FILE *fb);
I4 head1(tJpeg1 *jpg,FILE *f1);
I4 conv1a(tJpeg1 *jpg,FILE *f1);
I4 conv1b(tJpeg1 *jpg,FILE *f1);
I4 opts2(tProg *prg,int argc,char **argv);
xx jpeg2Beg(tJpeg2 *jpg);
xx jpeg2End(tJpeg2 *jpg);
int jpeg2a(int argc,char **argv);
I4 jpeg2b(tJpeg2 *jpg,FILE *fi,FILE *fb);
I4 conv2(N4 *nn,tJpeg2 *jpg,tSof *sof,tComp *comp,tComp2 *comp2,
  tHtab *htab,tQtab *qtab,tGetBit *bb,FILE *f1);

I4 GetBit(tGetBit *r1);
I4 GetVal(tGetBit *r1,N1 bits);
I4 Decode(tGetBit *r1,tHtab *htab);
I4 GetDC(tGetBit *r1,tHtab *htab,I2 *dc);
I4 GetAC(tGetBit *r1,tHtab *htab,I2 *ac);

I4 PutBit(tPutBit *r1,N1 b1);
I4 PutVal(tPutBit *r1,N2 v1,N1 l1);
I4 Encode(tPutBit *r1,tHtab *h1,N4 d1);
N1 GetSS(I2 *vv);
I4 Comp1(tHuf *h);
I4 Comp2(tHuf *h,N4 m1);

I4 PrepItem(tItem *itm);
I4 PrepLen1(tItem *itm,N1 *len);
I4 PrepLen2(tItem *itm,N1 *len);
I4 PrepVal(tItem *itm,N1 *val,N2 n1);
I4 PrepTab(tHtab *htab,N4 nn);

I4 DctInit(xx);
I4 ZigZag(N1 *zz,RI *dd1,RI *dd2);
I4 LevelShift1(N1 *dd1,RI *dd2);
I4 LevelShift2(RI *dd1,N1 *dd2);
I4 Quant1(N2 *q1,RI *dd1,I2 *dd2);
I4 Quant2(N2 *q1,I2 *dd1,RI *dd2);
I4 DCT1(RI *tt,RI *dd1,RI *dd2);
I4 DCT2(RI *tt,RI *dd1,RI *dd2);
R4 DCT1x(RI *tt,RI *dd,N1 u,N1 v);
R4 DCT2x(RI *tt,RI *dd,N1 x,N1 y);
xx Color1(N1 *cr,N1 *cg,N1 *cb);
xx Color2(N1 *c1,N1 *c2,N1 *c3);

I4 BmpRead1(tBmp *bmp,FILE *f1,
  N1 xd,N1 yd);
I4 BmpRead2(tBmp *bmp);
I4 BmpWrite1(tBmp *bmp,FILE *f1,
  N4 xm,N4 ym,N4 xl,N4 yl);
I4 BmpWrite2(tBmp *bmp);
I4 BmpGet(tBmp *bmp,N4 x,N4 y,
  N1 *cr,N1 *cg,N1 *cb);
I4 BmpSet(tBmp *bmp,N4 x,N4 y,
  N1 cr,N1 cg,N1 cb);


#endif
